{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "6ulPCn1AQgq4"
   },
   "source": [
    "![image.png]()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "378x9zFvp-Pt"
   },
   "source": [
    "### Installing dependencies"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "RRYSu48huSUW",
    "outputId": "f3f61ec3-4dc7-407f-c0ef-66f1266ab206"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
      "langchain-openai 0.1.23 requires langchain-core<0.3.0,>=0.2.35, but you have langchain-core 0.0.13 which is incompatible.\n",
      "langchain-openai 0.1.23 requires openai<2.0.0,>=1.40.0, but you have openai 0.28.0 which is incompatible.\n",
      "langchain-text-splitters 0.2.4 requires langchain-core<0.3.0,>=0.2.38, but you have langchain-core 0.0.13 which is incompatible.\u001b[0m\u001b[31m\n",
      "\u001b[0m"
     ]
    }
   ],
   "source": [
    "!pip install -U \"langchain==0.0.344\" \"openai==0.28\" tiktoken lark datasets sentence_transformers FlagEmbedding lancedb -qq"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "Q1NjujiOzLSs"
   },
   "source": [
    "### Importing libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "id": "IfCt8bhHNu9u"
   },
   "outputs": [],
   "source": [
    "from langchain.vectorstores import LanceDB\n",
    "from langchain.retrievers import ParentDocumentRetriever\n",
    "\n",
    "# Text Splitting\n",
    "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
    "from langchain.storage import InMemoryStore\n",
    "from langchain.docstore.document import Document\n",
    "\n",
    "from langchain.embeddings.openai import OpenAIEmbeddings\n",
    "from langchain.chains import RetrievalQA\n",
    "from langchain.llms import OpenAI\n",
    "\n",
    "import os\n",
    "from datasets import load_dataset\n",
    "\n",
    "from langchain.embeddings import HuggingFaceBgeEmbeddings\n",
    "import lancedb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "id": "O8pHMkQpzLSv"
   },
   "outputs": [],
   "source": [
    "os.environ[\"OPENAI_API_KEY\"] = \"sk-proj-....\"  # NEEDED if you run LLM Experiment below"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "gZmQ2vurzLSx"
   },
   "source": [
    "### Embeddings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 478,
     "referenced_widgets": [
      "cbed57ca766948ab97b7e9716d87a325",
      "bea5a78aee804baa9d4205575b0b6131",
      "271677554d7d48a68ff9ed96bd42c880",
      "f21b18ddc0074bc0bc818c170739c4c2",
      "e867f45fef14473aaa32e5cb89c83d2e",
      "00bcb263418b43c0a8e12d5878397554",
      "1bb2b1cc282b4025813cc7d19a0bbdeb",
      "29ed724bbcc1422c8a0f9d1e9f9dfb3f",
      "2fab5e7617e34ded8902b39e009e5bdb",
      "64b28de24514425eb9c31ada78a0810a",
      "593d5e863b924f7d903106c148f767c0",
      "f3a52ffb8ae642608dead0261d571702",
      "6f4fd4fcd04c4f948cab93687a5f4daa",
      "54e0a2395eed4ae29c790e9e567e2b3d",
      "e0e45e31316748ec8c661715a7fa3e03",
      "30cbb2739b25454180a8221716c05d90",
      "bb1fa329ae46498cbbf15143852e4c3d",
      "a63ddb5ed74642e48baa39f0b01bdcbf",
      "aa797229bee9416a8c29b58d5dfb346c",
      "94b7c7fbd5f04c0fb9664da8a5ed41b1",
      "b0b91bd411484a1fad3bf3eeb2b6540d",
      "5f456f46c7b4499fa4a40705169a379c",
      "d990cef595de4f908d4fb23a3deaa823",
      "78ead84761f64190a266fb9c9f4d1546",
      "90b8161882d5419993c77a42de2b413f",
      "59228687fae6494b8c3f3da04384aa5a",
      "d4be2d01b88e484ea72d2e762c90ffce",
      "416a0406c8ee4d16bab02aa93c561c73",
      "b8e84efcbb9746ecb033b432616997c1",
      "9c3146781f3348c5b98cfc1451c454d0",
      "bcbad39b5bd64d0c9a2e8314084baa2c",
      "e708e1cf4d3345a185fb0f401dff78de",
      "15c0b644303746639d8ecd9259dc6dee",
      "72ae5928ffb24855b57ed8fa65ccbfe8",
      "6e68085d643a41d884a9a2ab3de6d189",
      "2f7012f7794d47bb87512a5ff9cfb7d6",
      "683f1ef25dd04281aafab9f7ff72c5d4",
      "855a2cbe03b542ad9db45b80af140693",
      "db5fa58643054d77bf6799648299bd17",
      "b28eee9d4fd64c18a3fcee69237afa04",
      "628a4adc520c416aa9b9183f52f980fc",
      "335270df4649461d8815707311bbca0f",
      "988e8b0b5e244e70ab7ffe23c75dcf61",
      "10d00e194cf0467d97d071022fbe87a4",
      "f47f6330e35b4a6f8f1e4a5bcc0b790f",
      "f379cd5450534815b9388e4f4979afae",
      "d0df26b2cbbb41cd97183a93e2329806",
      "deb395bdbbaf4fbdbcb0585349a2f6ba",
      "73578928446e4341a12e39fd2146f04f",
      "8f3b9ed6ab4c4b48bffddb0449ef6384",
      "04340af8c9cf47f68d45decf58dbdd7b",
      "a7293b2c811a434296709a7b2da4d368",
      "9d0bb3f79a9a48c8bf2fa413cdf981e9",
      "5968ad4444124e4385f87f33e5934d05",
      "b7dbc35466474aa4aae898f544d757bb",
      "7afd4df43ead4704975409c68a5b0e86",
      "ddcc29ad56bb4550880d2f01f14705e3",
      "367f500fb231476193dff99304789e9f",
      "18c2ff6df0ad47e3becd23e9f79fef43",
      "ab940bf4c51c4a56a00e0133a4b6c578",
      "66f74c24e33842a48ef57e2711757bad",
      "83caecf1314942deadc718bfbf412b3d",
      "20371185d4094093a1607bc1391a51aa",
      "97f28f8e43f941e88e0e62665cd3fdab",
      "3cf16fb2cf4c4589903d16bd82c9de1b",
      "c30e152e105e40d2b30be37e4974ebe2",
      "f99341828e064181bd0b18947ba53519",
      "b853d2d210f04b5e931eb3edaf5a0288",
      "3b984a71ee8941a289255324c6faa57b",
      "cfcc1d98cb934d6f80efa9006b24f2fa",
      "84b68a0cfe924e5eb1f4514299086d8a",
      "5637d71b72f4404caceac012b82fcb36",
      "418e406cf86b4297b5f92061ed0fa5de",
      "d2719715af404f53a714e3eaac6611eb",
      "07469f41d1a846fd805011e20b0b3b9a",
      "6d91b6b000fb40c585525ed5d74bc137",
      "42dbc49816834ff2831df501d3358fac",
      "05cfab472d5f439d9fe1066ac610d5e9",
      "8c3e32eb50f94caa9e708a60ef042c64",
      "092b6cb38de247e08e9e7280f8c954d1",
      "c454ac9d62fb443ea27285b4d5b94b4f",
      "aa400e35649747f5ad335abaf3c943e6",
      "2172783eb30047f2b153d994fea90ba1",
      "4f8b4762d663473eb9f81cb6a0b153e1",
      "3d56501496cb4b3c843d919eeb6427ac",
      "35f7657060544513ae05da7ca73ce096",
      "a4409d13a67f498d975837d49cd5464f",
      "f17b863e2cd64abeb269c614b7b0f99f",
      "210cfd1e14794667beee16b9a5b27ea4",
      "314e31c7c5fd4c9c94ea9bd5da67d2b6",
      "83b7f062aa89479a90f7eee7e28d147e",
      "f050fb778bc84e52a0865f0688c40826",
      "971cc17be56d4b1e91e55a53527fdbb2",
      "43b8eac8233e4c8596e7109ca82ce23d",
      "822388df1462455abc3f053f90ee8d9c",
      "39a94ed18e864fa1ab98840ff0872509",
      "44806175d24b4efd9a5d4b20ad7ebd48",
      "ab10e61e844043c596b6fc9d61e79e71",
      "a558fbe7f75446329ed54292ce207efa",
      "e9865799f7ad4be68379f5a8575e4bf1",
      "644fa24b7f0f4121841f4d7916a4ec87",
      "be7b418e45994218a93534c8dec6e5e5",
      "869d136f42b94f1489e399bbf47731af",
      "3ea50918f2494d4484a429db77702ca7",
      "6c2e93a66cdb4395b7aee9ca37ea77f8",
      "26303941fa5d4ce6bf178e8631d08675",
      "6bb1d7057b724f67817cda1c5323003c",
      "b40a96404a2b42e994b9957921a938da",
      "04c5926fff3d43e5a34a0d733bd8d281",
      "c7bd634b83ce40f9af5dbde2def50d8e",
      "5816ce7c9a5649a79b43cce844f4aa11",
      "876d5b81ac8c4153923f2df9ee775750",
      "1147817d02f74fef814f96485603a518",
      "b6629a3573134bc9bcd6975c5d0f7859",
      "bf779bfdee8d42aa9986c7d480ca2941",
      "aeb01a623f044c94a4884dd14b622239",
      "b0c3785d8c9a4db295a20ee90bc32b44",
      "edf8995812924f319108a952413512f1",
      "0ad28f22cb274b2ab945160668bbc3d1",
      "f3d19e3bb53d4a87b3b58a6ea5d4da9e",
      "70101f8b17284f82b7d86b0a240a874c"
     ]
    },
    "id": "og-GCq6fzLSy",
    "outputId": "922e833b-f222-497a-b88a-94efd55da436"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.10/dist-packages/huggingface_hub/utils/_token.py:89: UserWarning: \n",
      "The secret `HF_TOKEN` does not exist in your Colab secrets.\n",
      "To authenticate with the Hugging Face Hub, create a token in your settings tab (https://huggingface.co/settings/tokens), set it as secret in your Google Colab and restart your session.\n",
      "You will be able to reuse this secret in all of your notebooks.\n",
      "Please note that authentication is recommended but still optional to access public models or datasets.\n",
      "  warnings.warn(\n"
     ]
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "cbed57ca766948ab97b7e9716d87a325",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "modules.json:   0%|          | 0.00/349 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f3a52ffb8ae642608dead0261d571702",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "config_sentence_transformers.json:   0%|          | 0.00/124 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "d990cef595de4f908d4fb23a3deaa823",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "README.md:   0%|          | 0.00/94.8k [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "72ae5928ffb24855b57ed8fa65ccbfe8",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "sentence_bert_config.json:   0%|          | 0.00/52.0 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f47f6330e35b4a6f8f1e4a5bcc0b790f",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "config.json:   0%|          | 0.00/743 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "7afd4df43ead4704975409c68a5b0e86",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "model.safetensors:   0%|          | 0.00/133M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "f99341828e064181bd0b18947ba53519",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "tokenizer_config.json:   0%|          | 0.00/366 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "05cfab472d5f439d9fe1066ac610d5e9",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "vocab.txt:   0%|          | 0.00/232k [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "210cfd1e14794667beee16b9a5b27ea4",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "tokenizer.json:   0%|          | 0.00/711k [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e9865799f7ad4be68379f5a8575e4bf1",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "special_tokens_map.json:   0%|          | 0.00/125 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "5816ce7c9a5649a79b43cce844f4aa11",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "1_Pooling/config.json:   0%|          | 0.00/190 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Embedding Functions\n",
    "model_name = \"BAAI/bge-small-en-v1.5\"  # Open Source and effective Embedding\n",
    "encode_kwargs = {\"normalize_embeddings\": True}  # set True to compute cosine similarity\n",
    "bge_embeddings = HuggingFaceBgeEmbeddings(\n",
    "    model_name=model_name, model_kwargs={\"device\": \"cuda\"}, encode_kwargs=encode_kwargs\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "wRFFQhomzLS0"
   },
   "source": [
    "### Chunk the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "id": "9uJBRFW9zLS1"
   },
   "outputs": [],
   "source": [
    "# Data Chunking Functions\n",
    "small_chunk_splitter = RecursiveCharacterTextSplitter(\n",
    "    chunk_size=512\n",
    ")  # Splitter to split documents into small chunks\n",
    "big_chunk_splitter = RecursiveCharacterTextSplitter(\n",
    "    chunk_size=2048\n",
    ")  # Another Level of Bigger Chunks"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "_AgrvLiozLS2"
   },
   "source": [
    "## LanceDB connection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "F4xuShlW1yY_"
   },
   "outputs": [],
   "source": [
    "# Lance DB Connection. Load if exists else create\n",
    "my_db = lancedb.connect(\"./my_db\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "rYAe6EEtHnzf"
   },
   "source": [
    "# Load [Eminem Lyrics Dataset](https://huggingface.co/huggingartists/eminem)\n",
    "\n",
    "Convert it to a `LangChain` Documents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 81,
     "referenced_widgets": [
      "927693586039450694e9b31d34a7c50e",
      "0cb6c03151494a1494539c933a27cd7d",
      "0d085ac192a64fedae57eaaa31de2263",
      "b952dade042845858328fdf67f9ecb27",
      "11ab05e4e6f64d6ea70da20a4d0e3f66",
      "7d612741aae843da8b782f8c882b1d7a",
      "b6552407735c4b14800ef6975aa41de7",
      "53ad8af1be724d11ad3e23429756c54c",
      "348d43f57e1f4e9a99174771bb083b96",
      "af655fbf52744fb08606704df15787c2",
      "0ac9d4aab9324e08bb59a5a23a94417b",
      "fa1f63dabb5947fb9db5c4d3b9ef8a19",
      "d19368fb264e46f38e6aa7a127a336c0",
      "9420f79829bc40cb91488a7fc970fdf2",
      "9992efe0b644432ebd45060535703cdb",
      "61a5faf6867d435b9216b53cf04d15a7",
      "1f1d6038f4ec4d788b46aaacd2c68283",
      "819a0f5a83084f5da4fbbac12a65a911",
      "bdc6868d99784999b1d33640dd4bd076",
      "1a6ef7683f5e4cd89c22c4fb08006584",
      "5c46c5f258aa4ca1b3f44d5b6eddb545",
      "b618885a6d5244cf9864cb1be0c99eb7"
     ]
    },
    "id": "ww32NJxOHuLc",
    "outputId": "054d38b2-3627-4993-f5d1-0bca6c98aaa0"
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "927693586039450694e9b31d34a7c50e",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading data:   0%|          | 0.00/2.47M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "fa1f63dabb5947fb9db5c4d3b9ef8a19",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Generating train split:   0%|          | 0/1285 [00:00<?, ? examples/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Load a sample data here\n",
    "long_texts = (\n",
    "    load_dataset(\"huggingartists/eminem\")[\"train\"].to_pandas().sample(100)[\"text\"]\n",
    ")  # Data of huge context length. Use 100 random examples for demo\n",
    "\n",
    "# Convert to LangChain Document object\n",
    "docs = [\n",
    "    Document(page_content=content, doc_id=_id, metadata={\"doc_id\": _id})\n",
    "    for (_id, content) in enumerate(long_texts)\n",
    "]  # List of LangChain Document Objects"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "paJBIbScI4mn"
   },
   "source": [
    "# Method 1: Retrieve Parent Document\n",
    "\n",
    "When you run a Query, match it against the **smaller** chunks and retrieve it's Parent Document for passing to LLM as a context"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "id": "nYdeZNU495Bi"
   },
   "outputs": [],
   "source": [
    "!rm -rf ./my_db"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "id": "1OAY1gQl2luo"
   },
   "outputs": [],
   "source": [
    "if \"small_chunk_table\" in my_db.table_names():\n",
    "    small_chunk_table = my_db.open_table(\"small_chunk_table\")\n",
    "else:  # NOTE: 384 is the size of BAAI Embedding and -999 because it's a dummy data so invalid Embedding\n",
    "    small_chunk_table = my_db.create_table(\n",
    "        \"small_chunk_table\",\n",
    "        data=[\n",
    "            {\n",
    "                \"vector\": [-999] * 384,\n",
    "                \"text\": \"\",\n",
    "                \"doc_id\": \"-1\",\n",
    "            }\n",
    "        ],\n",
    "        mode=\"overwrite\",\n",
    "    )\n",
    "\n",
    "small_chunk_table.delete('doc_id = \"-1\"')\n",
    "\n",
    "vectorstore = LanceDB(\n",
    "    small_chunk_table, bge_embeddings\n",
    ")  # Vectorstore to use to index the child chunks\n",
    "store = InMemoryStore()  # The storage layer for the parent documents\n",
    "\n",
    "full_doc_retriever = ParentDocumentRetriever(\n",
    "    vectorstore=vectorstore, docstore=store, child_splitter=small_chunk_splitter\n",
    ")\n",
    "\n",
    "full_doc_retriever.add_documents(docs, ids=None)  # Add all the documents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "myyqiovlsqyG",
    "outputId": "82a8a0ba-d6a0-4ef8-8d71-526b22049786"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "You are a true Queen, and I mean that in every sense of the word. I will never forget the opportunities you have given me. You will always be in my heart, my thoughts, and my prayers. As I have said before, you have no idea how much your son and his music has inspired, not only the Hip Hop world, but, speaking for myself, has inspired my whole career. He was, and still is, the true definition of a Soldier. When I was feeling at my worst; I knew I could put that 2Pac tape in, and suddenly, things werent so\n"
     ]
    }
   ],
   "source": [
    "# Fetch 3 most similar Smaller Documents\n",
    "sub_docs = vectorstore.similarity_search(\n",
    "    \"I am whatever you say I am and if I wasn't why would you say I am\", k=3\n",
    ")\n",
    "\n",
    "print(sub_docs[0].page_content)  # This is a Smaller Chunk"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "bnJhjNQZeLry",
    "outputId": "67761eb4-9cdb-4a40-c9e5-88590c315a88"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Letter to Tupac’s Mother LyricsDear Afeni\n",
      "Sorry if it looks a little sloppy, I couldve done a little better if I had the right pencils. Instead, I had to draw it in pen. Plus, I just kind of thought of the idea a little too late. But Ive been drawing since I was 10, and I thought you might like it. Anyways, thank you for always being so kind to me. You are a true Queen, and I mean that in every sense of the word. I will never forget the opportunities you have given me. You will always be in my heart, my thoughts, and my prayers. As I have said before, you have no idea how much your son and his music has inspired, not only the Hip Hop world, but, speaking for myself, has inspired my whole career. He was, and still is, the true definition of a Soldier. When I was feeling at my worst; I knew I could put that 2Pac tape in, and suddenly, things werent so bad. He gave me the courage to stand up and say Fk the world! This is who I am! And if you dont like it, go fk yourself! Thank you for giving us his spirit, and yours! God Bless you!\n",
      "Love\n",
      "Marshall17Embed\n"
     ]
    }
   ],
   "source": [
    "full_docs = full_doc_retriever.get_relevant_documents(\n",
    "    \"I am whatever you say I am and if I wasn't why would you say I am\", k=3\n",
    ")\n",
    "print(\n",
    "    full_docs[0].page_content\n",
    ")  # This is the Parent Document returned after matching the smaller chunks internally"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "OsYuq1KDebLW"
   },
   "source": [
    "#  Method 2: Retrieving Larger chunks\n",
    "\n",
    "If, small chunks are not needed as they don't have the whole context BUT the full documents are too big to be needing or fitting into LLM, we split the raw documents into larger chunks, and then split it into smaller chunks. Then index the smaller chunks, but on retrieval we retrieve the larger chunks as a replacement of full documents."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "id": "SbijhNnmegYs"
   },
   "outputs": [],
   "source": [
    "if \"big_chunk_table\" in my_db.table_names():\n",
    "    big_chunk_table = my_db.open_table(\"big_chunk_table\")\n",
    "else:\n",
    "    big_chunk_table = my_db.create_table(\n",
    "        \"big_chunk_table\",\n",
    "        data=[\n",
    "            {\n",
    "                \"vector\": [-999] * 384,\n",
    "                \"text\": \"\",\n",
    "                \"doc_id\": \"-1\",\n",
    "            }\n",
    "        ],\n",
    "        mode=\"overwrite\",\n",
    "    )\n",
    "\n",
    "big_chunk_table.delete('doc_id = \"-1\"')\n",
    "\n",
    "vectorstore = LanceDB(big_chunk_table, bge_embeddings)\n",
    "store = InMemoryStore()\n",
    "\n",
    "big_chunk_retriever = ParentDocumentRetriever(\n",
    "    vectorstore=vectorstore,\n",
    "    docstore=store,\n",
    "    child_splitter=small_chunk_splitter,\n",
    "    parent_splitter=big_chunk_splitter,\n",
    ")  # See one more line addition which retrieves the larger chunk instead of Parent Document\n",
    "\n",
    "big_chunk_retriever.add_documents(docs, ids=None)  # Add all the documents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "TP6dx1L1eg1r",
    "outputId": "5c9c9c04-dfb1-460f-eab1-efe07f0228dd"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Letter to Tupac’s Mother LyricsDear Afeni\n",
      "Sorry if it looks a little sloppy, I couldve done a little better if I had the right pencils. Instead, I had to draw it in pen. Plus, I just kind of thought of the idea a little too late. But Ive been drawing since I was 10, and I thought you might like it. Anyways, thank you for always being so kind to me. You are a true Queen, and I mean that in every sense of the word. I will never forget the opportunities you have given me. You will always be in my heart, my thoughts, and my prayers. As I have said before, you have no idea how much your son and his music has inspired, not only the Hip Hop world, but, speaking for myself, has inspired my whole career. He was, and still is, the true definition of a Soldier. When I was feeling at my worst; I knew I could put that 2Pac tape in, and suddenly, things werent so bad. He gave me the courage to stand up and say Fk the world! This is who I am! And if you dont like it, go fk yourself! Thank you for giving us his spirit, and yours! God Bless you!\n",
      "Love\n",
      "Marshall17Embed\n"
     ]
    }
   ],
   "source": [
    "big_chunks_docs = big_chunk_retriever.get_relevant_documents(\n",
    "    \"I am whatever you say I am and if I wasn't why would you say I am\", k=3\n",
    ")\n",
    "print(\n",
    "    big_chunks_docs[0].page_content\n",
    ")  # This is the BIG chunks (in place of Parent Document) returned after matching the smaller chunks internally"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "wo8g8eiNHVvx"
   },
   "source": [
    "# Dummy LLM Use"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "KKtSLm5PyNay",
    "outputId": "7507181b-e2de-422c-a7a2-413a0ba4688d"
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/usr/local/lib/python3.10/dist-packages/langchain/llms/openai.py:244: UserWarning: You are trying to use a chat model. This way of initializing it is no longer supported. Instead, please use: `from langchain.chat_models import ChatOpenAI`\n",
      "  warnings.warn(\n",
      "/usr/local/lib/python3.10/dist-packages/langchain/llms/openai.py:1043: UserWarning: You are trying to use a chat model. This way of initializing it is no longer supported. Instead, please use: `from langchain.chat_models import ChatOpenAI`\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "source": [
    "qa = RetrievalQA.from_chain_type(\n",
    "    llm=OpenAI(model_name=\"gpt-4\"),\n",
    "    chain_type=\"stuff\",\n",
    "    retriever=big_chunk_retriever,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "id": "FN7HvpmQ3cpM"
   },
   "outputs": [],
   "source": [
    "query = (\n",
    "    \"I am whatever you say I am and if I wasn't why would you say I am? So who is Em?\"\n",
    ")\n",
    "result = qa({\"query\": query})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 36
    },
    "id": "30tYA4sOD4Rq",
    "outputId": "60f7b66d-c154-4c93-ae16-6df4346ab016"
   },
   "outputs": [
    {
     "data": {
      "application/vnd.google.colaboratory.intrinsic+json": {
       "type": "string"
      },
      "text/plain": [
       "'Em refers to Eminem, the rapper. His real name is Marshall Mathers, as indicated in the \"Letter to Tupac’s Mother Lyrics\". Eminem often refers to himself as \"Em\" in his music.'"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "result[\"result\"]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "JQq3cH-RIvwi"
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "accelerator": "GPU",
  "colab": {
   "gpuType": "T4",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
